class Snake {
    content: HTMLElement | null;
    head: HTMLElement | null;
    bodies: HTMLCollection | null;

    constructor() {
        this.content = document.getElementById('snake');
        this.head = document.querySelector('#snake > div');
        this.bodies = this.content!.getElementsByTagName('div');
    }

    get X() {
        return this.head!.offsetLeft;
    }

    get Y() {
        return this.head!.offsetTop;
    }

    set X(value: number) {
        if (value === this.X) return;
        if (value < 0 || value > 290) throw new Error('游戏结束');

        if (this.bodies?.[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {
            if (value > this.X) {
                value = this.X - 10;
            } else {
                value = this.X + 10;
            }
        }

        this.moveBody();
        this.head!.style.left = value + 'px';
        this.checkHeadBody();
    }

    set Y(value: number) {
        if (value === this.Y) return;
        if (value < 0 || value > 290) throw new Error('游戏结束');

        if (this.bodies?.[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {
            if (value > this.Y) {
                value = this.Y - 10;
            } else {
                value = this.Y + 10;
            }
        }

        this.moveBody();
        this.head!.style.top = value + 'px';
        this.checkHeadBody();
    }

    // 蛇增加身体
    addBody() {
        this.content?.insertAdjacentHTML('beforeend', '<div></div>');
    }

    moveBody() {
        // 后一节等于前一节位置
        for (let i = this.bodies!.length - 1; i > 0; i--) {
            let x = (this.bodies?.[i - 1] as HTMLElement).offsetLeft;
            let y = (this.bodies?.[i - 1] as HTMLElement).offsetTop;

            (this.bodies?.[i] as HTMLElement).style.top = y + 'px';
            (this.bodies?.[i] as HTMLElement).style.left = x + 'px';
        }
    }

    // 检查身体是否碰撞
    checkHeadBody() {
        for (let i = 1; i < this.bodies!.length; i++) {
            let body = this!.bodies?.[i] as HTMLElement;
            if (body.offsetLeft === this.X && body.offsetTop === this.Y) {
                throw new Error('游戏结束');
            }
        }
    }
}

export default Snake;
